/*
 * @Version: V1.0
 * @Project: MGS组件 All rights Reserved, Designed By www.supermap.com
 * @Title:
 * @Package: mgs-webui-basic
 * @Description:
 * @Author: 李卫欣
 * @Date: 2021-06-20 17:29:07
 * @Copyright: 2021 www.supermap.com Inc. All rights reserved.
 * @注意: 本内容仅限于北京超图信息技术有限公司内部传阅，禁止外泄以及用于其他的商业目的
 */
import type { BindMap } from 'types'
import * as Cesium from 'Cesium'

export default class GraticulesPlugin {
    static extends = [
        'openGraticules',
        'closeGraticules',
        'openGLabel',
        'closeGLabel',
    ]

    private showGLable__!: Boolean

    private map: any

    private graticulesGroup__ = new Cesium.CustomDataSource()
    //内存绘注记制层
    private gLabelGroup__ = new Cesium.CustomDataSource()

    private isOpen__ = false

    private currentBounds__!: number[]

    private currentZoomLvl__ = 1

    private vmParent: any

    //经纬网 样式
    private graticulesStyle__: any

    constructor(vm: BindMap) {
        this.vmParent = vm
        this.map = vm.map
        this.map.dataSources.add(this.graticulesGroup__)
        this.map.dataSources.add(this.gLabelGroup__)
        this.showGLable__ = false
    }

    openGraticules(isLabel: boolean = false, style: any) {
        this.isOpen__ = true
        this.showGLable__ = isLabel
        this.graticulesStyle__ = style
        this.vmParent.$on('onZoomEnd', this._onMapZoomEnd.bind(this))
        this.drawGraticules(this.vmParent.getZoom(), this.vmParent.getBounds())
    }

    closeGraticules() {
        this.isOpen__ = false
        this.showGLable__ = false
        this.graticulesStyle__ = {}
        this.vmParent.$off('onZoomEnd', this._onMapZoomEnd)
        this.graticulesGroup__.entities.removeAll()
        this.gLabelGroup__.entities.removeAll()
    }

    openGLabel() {
        this.showGLable__ = true
        this.closeGraticules()
        this.openGraticules(true, this.graticulesStyle__)
    }

    closeGLabel() {
        this.showGLable__ = false
        // this.closeGraticules()
        // this.openGraticules()
        this.gLabelGroup__.entities.removeAll()
    }

    _onMapZoomEnd(e: any) {
        this.currentBounds__ = this.vmParent.getBounds()
        this.currentZoomLvl__ = this.vmParent.getZoom()
        if (!this.isOpen__) {
            return
        }
        this.drawGraticules(this.vmParent.getZoom(), this.vmParent.getBounds())
    }

    drawGraticules(zoomLvl: number, bounds: number[]) {
        let w: number = bounds[0]
        let s: number = bounds[1]
        let e: number = bounds[2]
        let n: number = bounds[3]
        //取跨度
        let step: number = 1
        if (this.currentZoomLvl__ < 3) {
            step = 10
        } else if (this.currentZoomLvl__ < 6) {
            step = 5
        }
        const lbW = w
        const lbN = n
        //直接取整 w s
        w = Math.floor(w)
        s = Math.floor(s)
        switch (step) {
            case 5:
                w = Math.floor(w / 5) * 5
                s = Math.floor(s / 5) * 5
                break
            case 10:
                w = Math.floor(w / 10) * 10
                s = Math.floor(s / 10) * 10
                break
        }
        if (w < -180) {
            w = -180
        }
        if (s < -90) {
            s = -90
        }
        //取整加1 e n
        e = Math.ceil(e)
        if (e > 180) {
            e = 180
        }
        n = Math.ceil(n)
        if (n > 90) {
            n = 90
        }
        //清除原网格
        this.graticulesGroup__.entities.removeAll()
        this.gLabelGroup__.entities.removeAll()
        //设置风格样式
        const selfStyle = Object.assign(
            {
                fontColor: this.graticulesStyle__.color || '#666',
                fill: this.graticulesStyle__.fill || true,
            },
            this.graticulesStyle__
        )
        this.graticulesStyle__ = selfStyle
        //开始画网格
        const self = this
        let r = 0,
            c = 0
        for (let lng = w; lng < e + 1 && lng < 181; lng += step) {
            for (let lat = s; lat < n + 1 && lat < 91; lat += step) {
                this.graticulesGroup__.entities.add(
                    new Cesium.Entity({
                        polyline: new Cesium.PolylineGraphics({
                            positions: Cesium.Cartesian3.fromDegreesArray([
                                lng,
                                lat,
                                lng,
                                lat + step,
                                lng + step,
                                lat + step,
                                lng + step,
                                lat,
                            ]),
                            clampToGround: new Cesium.ConstantProperty(true),
                            width: new Cesium.ConstantProperty(2),
                            material: new Cesium.ColorMaterialProperty(
                                Cesium.Color.fromCssColorString(
                                    selfStyle.fontColor
                                )
                            ),
                        }),
                        polygon: new Cesium.PolygonGraphics({
                            hierarchy: new Cesium.PolygonHierarchy(
                                Cesium.Cartesian3.fromDegreesArray([
                                    lng,
                                    lat,
                                    lng,
                                    lat + step,
                                    lng + step,
                                    lat + step,
                                    lng + step,
                                    lat,
                                ])
                            ),
                            heightReference: new Cesium.ConstantProperty(
                                Cesium.HeightReference.CLAMP_TO_GROUND
                            ),
                            material: new Cesium.ColorMaterialProperty(
                                Cesium.Color.TRANSPARENT
                            ),
                        }),
                    })
                )
                if (this.showGLable__) {
                    if (r === 1) {
                        //纬度
                        this.vmParent.drawGraphic(
                            'Label',
                            [lbW, lat],
                            {
                                text: `${lat}°`,
                                disableDepthTestDistance:
                                    Number.POSITIVE_INFINITY,
                                offset: [-25, 0],
                                ...selfStyle,
                            },
                            null,
                            this.gLabelGroup__
                        )
                    }
                    if (c === 1) {
                        //经度
                        this.vmParent.drawGraphic(
                            'Label',
                            [lng, lbN],
                            {
                                text: `${lng}°`,
                                disableDepthTestDistance:
                                    Number.POSITIVE_INFINITY,
                                offset: [0, -25],
                                ...selfStyle,
                            },
                            null,
                            this.gLabelGroup__
                        )
                    }
                }
                c++
            }
            r++
            c = 0
        }
    }
}
